package kz.edu.sdu.itech.pcs.mclient;

import java.util.HashMap;

import kz.edu.sdu.itech.pcs.common.Alphabet;
import kz.edu.sdu.itech.pcs.common.Message;
import kz.edu.sdu.itech.pcs.common.MessageType;
import kz.edu.sdu.itech.pcs.common.ServerStatus;

import org.apache.log4j.Logger;

public class Server {
   static Logger log = Logger.getLogger(Server.class);

   Monitor monitor;

   private Alphabet alphabet;
   private int len;
   private int hash;

   private ServerStatus status = ServerStatus.WAITING;
   private double done = 0;
   private double count = 0;
   private HashMap<String, String> workers = new HashMap<String, String>();

   public void loadJob() {
      Message m = new Message();
      m.setType(MessageType.JOB);
      handleResponse(monitor.request(m));
   }

   public void setupWork() {
      Message m = new Message();
      m.setType(MessageType.SETUP);
      m.addArg("alphabet", getAlphabet().toString());
      m.addArg("len", "" + len);
      m.addArg("hash", "" + hash);
      handleResponse(monitor.request(m));
   }

   public void startWork() {
      Message m = new Message();
      m.setType(MessageType.START);
      handleResponse(monitor.request(m));
   }

   public void stopWork() {
      Message m = new Message();
      m.setType(MessageType.STOP);
      handleResponse(monitor.request(m));
   }

   public void refresh() {
      Message m = new Message();
      m.setType(MessageType.SERVERSTATUS);
      handleResponse(monitor.request(m));
   }

   public void loadWorkers() {
      Message m = new Message();
      m.setType(MessageType.CLIENTS);
      handleResponse(monitor.request(m));
   }

   public HashMap<String, String> getWorkers() {
      return workers;
   }

   public void handleResponse(MessageFromServer res) {
      if (res == null) {
         log.debug(String.format("no connection with %s", monitor.getSomeName()));
         return;
      }
      if (res.getType().equals(MessageType.START)) {
         String n = res.getArgs().get("msg");
         if (n.equals(Monitor.OK)) {
            setStatus(ServerStatus.RUNNING);
            setDone(0);
         }
      } else if (res.getType().equals(MessageType.STOP)) {
         String n = res.getArgs().get("msg");
         if (n.equals(Monitor.OK)) {
            setStatus(ServerStatus.WAITING);
         }
      } else if (res.getType().equals(MessageType.COND)) {

      } else if (res.getType().equals(MessageType.SERVERSTATUS)) {
         setStatus(ServerStatus.valueOf(res.getArgs().get("STATUS")));
      } else if (res.getType().equals(MessageType.JOB)) {
         if (res.getArgs().get("msg").equals("msg"))
            return;
         alphabet = new Alphabet();
         alphabet.add(res.getArgs().get("alphabet"));
         log.debug("LENGTH");
         log.debug(res.getArgs().get("len"));
         len = Integer.parseInt(res.getArgs().get("len"));
         hash = Integer.parseInt(res.getArgs().get("hash"));

         done = Integer.parseInt(res.getArgs().get("done"));
         count = Integer.parseInt(res.getArgs().get("count"));
      } else if (res.getType().equals(MessageType.CLIENTS)) {
//         log.debug(res.getArgs().get("CLIENTS"));
//         workers.clear();
         workers = res.getArgs();
      } else if (res.getType().equals(MessageType.SETUP)) {
         setStatus(ServerStatus.valueOf(res.getArgs().get("STATUS")));
      }
   }

   //=================================================

   public Server(Monitor monitor) {
      this.monitor = monitor;
   }

   public Alphabet getAlphabet() {
      if (alphabet == null) {
         alphabet = new Alphabet();
      }
      return alphabet;
   }

   public void setAlphabet(Alphabet alphabet) {
      this.alphabet = alphabet;
   }

   public int getLen() {
      return len;
   }

   public void setLen(int len) {
      this.len = len;
   }

   public int getHash() {
      return hash;
   }

   public void setHash(int hash) {
      this.hash = hash;
   }

   public ServerStatus getStatus() {
      return status;
   }

   public void setStatus(ServerStatus status) {
      this.status = status;
   }

   public double getDone() {
      return done;
   }

   public void setDone(double done) {
      this.done = done;
   }

   public double getCount() {
      return count;
   }

}
